package com.zoe.tree.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zoe.Zhang
 * @date 2022/05/09
 * @description
 */
public class LambdaUtils {
    /**
     * List转Map,key值可以重复,如果key有重复值,那么作为一组数据
     * 按照性别分组；
     * @param collection 源数据
     * @param key        key值
     * @return
     * @example Map<Integer, List < User>> integerListMap = LambdaUtils.listToGroupMap(usersList, User::getSex);
     */
    public static <K, T> Map<K, List<T>> listToGroupMap(Collection<T> collection, Function<T, K> key) {
        return collection.stream()
                         .collect(Collectors.groupingBy(key));
    }

    /**
     * List转Map,key值不可以重复,如果存在重复key,后者覆盖前者
     * @param collection 源数据
     * @param key        key值
     * @return
     * @example Map<Integer, User> userMap = LambdaUtils.listToMap(usersList, User::getId);
     */
    public static <K, T> Map<K, T> listToMap(Collection<T> collection, Function<T, K> key) {
        return collection.stream()
                         .collect(Collectors.toMap(key, Function.identity(), (k1, k2) -> k2));
    }

    /**
     * List<Obj>过滤出obj中的某个属性
     * @param collection 源数据
     * @param key        属性值 T = 源数据类型， K = 返回数据类型
     * @return
     * @example List<String> nameList = LambdaUtils.mappingList(usersList, User::getName);
     */
    public static <K, T> List<K> mappingList(Collection<T> collection, Function<T, K> key) {
        return collection.stream()
                         .map(key).collect(Collectors.toList());
    }

    public static <T> List<T> sortList(Collection<T> collection, Comparator<T> comparing) {
        return collection.stream()
                         .sorted(comparing).collect(Collectors.toList());
    }


    /**
     * char转list并赋值
     * @param entity
     * @param function
     * @param biConsumer
     * @param <ENTITY>
     */
    public static <ENTITY> void charToList(ENTITY entity, Function<ENTITY, String> function,
                                           BiConsumer<ENTITY, List<String>> biConsumer) {
        try {
            if (ObjectUtil.isNull(entity)) {
                return;
            }
            String apply = function.apply(entity);
            if (StrUtil.isBlank(apply)) {
                return;
            }
            List<String> strings = StrUtil.split(apply, ",");
            biConsumer.accept(entity, strings);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * list转char并赋值
     * @param entity
     * @param function
     * @param biConsumer
     * @param <ENTITY>
     */
    public static <ENTITY> void listToChar(ENTITY entity, Function<ENTITY, List<String>> function,
                                           BiConsumer<ENTITY, String> biConsumer) {
        try {
            if (ObjectUtil.isNull(entity)) {
                return;
            }
            List<String> apply = function.apply(entity);
            if (CollUtil.isEmpty(apply)) {
                biConsumer.accept(entity, "");
                return;
            }

            String str = StrUtil.join(",", apply);
            biConsumer.accept(entity, str);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
